home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-03 / bc7eqget.zip / QB4INT.DOC < prev   
Text File  |  1989-12-20  |  11KB  |  311 lines

  1. The application note below is supported by Microsoft QuickBASIC
  2. Versions 4.00, 4.00b, and 4.50 for MS-DOS and Microsoft BASIC Compiler
  3. Versions 6.00 and 6.00b for MS-DOS.
  4.  
  5. With slight changes, this information also applies to the Microsoft
  6. BASIC PDS Version 7.00 for MS-DOS. References in this documentation to
  7. several filenames should be changed if you use CALL INTERRUPT under
  8. BASIC PDS 7.00, as follows:
  9.  
  10.    Name Referred To               BASIC PDS 7.00 Name
  11.    ----------------               -------------------
  12.  
  13.         QB.QLB                          QBX.QLB
  14.         QB.LIB                          QBX.LIB
  15.         QB.BI                           QBX.BI
  16.  
  17. CALL INTERRUPT is a complicated statement that allows programmers
  18. access to low-level MS-DOS and BIOS information and control from
  19. QuickBASIC. Effective use of the complex CALL INTERRUPT interface
  20. requires understanding of the QuickBASIC programming environment, the
  21. BASIC language, and lower-level DOS and BIOS functions. This
  22. application note explains many of these necessary features, including
  23. the following:
  24.  
  25. 1. Libraries and Quick libraries
  26.  
  27. 2. User-defined TYPEs
  28.  
  29. 3. INCLUDE files
  30.  
  31. 4. CALL INTERRUPT input and output
  32.  
  33. 5. Example of CALL INTERRUPT
  34.  
  35. 6. Differences between CALL INTERRUPT and CALL INTERRUPTX
  36.  
  37. 7. References for documentation on INTERRUPTs
  38.  
  39. The CALL INTERRUPT statement documented in this application note is
  40. supported in Microsoft QuickBASIC 4.00 and later. In QuickBASIC 2.00,
  41. 2.01, and 3.00, CALL INT86 provides access to the BIOS and DOS
  42. INTERRUPTs using an array interface instead of user-defined TYPEs.
  43. CALL INT86 is documented on Pages 148-149 of the "Microsoft QuickBASIC
  44. Compiler" manual for Versions 2.00, 2.01, and 3.00. Although there are
  45. differences, some of the information in this application note will be
  46. useful to those who use QuickBASIC 2.00, 2.01, and 3.00.
  47.  
  48. The CALL INTERRUPT statement is not supported in OS/2 protected mode.
  49. Most of the functions provided by the INTERRUPTs are available in
  50. protected mode, but are accessed through API (application program
  51. interface) calls. The INTERRUPTs will work correctly in OS/2's real
  52. mode, with a few exceptions.
  53.  
  54. More Information:
  55.  
  56. Libraries and Quick Libraries
  57. -----------------------------
  58.  
  59. The object code for the INTERRUPT routines is located in the QB.LIB
  60. and QB.QLB Quick libraries, which are supplied with QuickBASIC 4.00,
  61. 4.00b, and 4.50 and BASIC compiler 6.00 and 6.00b.
  62.  
  63. The difference between libraries (.LIB) and Quick libraries (.QLB) is
  64. that Quick libraries are used within the QuickBASIC environment,
  65. whereas libraries are used (at link time) to produce executable
  66. programs.
  67.  
  68. To load a Quick library for use with the QuickBASIC environment, you
  69. must enter QuickBASIC with the /L option (e.g. "QB /L QB.QLB"). This
  70. will allow you to make CALLs to the routines in that Quick library.
  71. When you choose Make EXE File from the Run menu, your program will be
  72. automatically linked with the library (.LIB) of the same name as your
  73. Quick library; in this case, it would be QB.LIB.
  74.  
  75. User-Defined TYPEs
  76. ------------------
  77.  
  78. To use the CALL INTERRUPT statement, you must first create a
  79. user-defined TYPE to contain the registers for the INTERRUPT. The
  80. TYPEs defined in the INCLUDE file (QB.BI) that comes with QuickBASIC
  81. 4.00, 4.00b, and 4.50 are as follows:
  82.  
  83. TYPE RegType
  84.      ax    AS INTEGER
  85.      bx    AS INTEGER
  86.      cx    AS INTEGER
  87.      dx    AS INTEGER
  88.      bp    AS INTEGER
  89.      si    AS INTEGER
  90.      di    AS INTEGER
  91.      flags AS INTEGER
  92. END TYPE
  93.  
  94. TYPE RegTypeX                     ' See NOTE
  95.      ax    AS INTEGER
  96.      bx    AS INTEGER
  97.      cx    AS INTEGER
  98.      dx    AS INTEGER
  99.      bp    AS INTEGER
  100.      si    AS INTEGER
  101.      di    AS INTEGER
  102.      flags AS INTEGER
  103.      ds    AS INTEGER
  104.      es    AS INTEGER
  105. END TYPE
  106.  
  107. Note: RegTypeX is used with the CALL INTERRUPTX statement, which
  108. allows you to specify the DS and ES registers. For more information,
  109. please refer to the section below titled "Differences between CALL
  110. INTERRUPT and CALL INTERRUPTX."
  111.  
  112. INCLUDE Files
  113. -------------
  114.  
  115. To simplify the TYPE definition for INTERRUPTs, the INCLUDE file,
  116. QB.BI, is shipped with QuickBASIC 4.00 and 4.50. This file has the
  117. TYPE definitions (see above) and SUB DECLARations needed for
  118. INTERRUPTs. To use this file, the metacommand $INCLUDE must be placed
  119. at the beginning of your code. The syntax of this statement is as
  120. follows:
  121.  
  122.    REM $INCLUDE: 'QB.BI'
  123.  
  124. Please note the following:
  125.  
  126. 1. Metacommands are placed in comments (REM).
  127.  
  128. 2. A colon (:) follows the $INCLUDE.
  129.  
  130. 3. The filename (QB.BI) is enclosed in single quotation marks.
  131.  
  132. CALL INTERRUPT Input and Output
  133. -------------------------------
  134.  
  135. Besides the INTERRUPT number, there are two other parameters for the
  136. CALL INTERRUPT statement: the input registers and the output
  137. registers. Before you use these registers, you must dimension two
  138. variables AS the RegType defined above, as follows:
  139.  
  140.    DIM inregs AS RegType, outregs AS RegType
  141.  
  142. For most INTERRUPTs, you need to pass some information (function
  143. number, function parameters) in one or more of the registers. This
  144. assignment is done using the dot (.) operator, as follows:
  145.  
  146.    inregs.AX = &H1A00
  147.  
  148. Note that the above assignment uses the hexadecimal value -- denoted
  149. by the "&H"-- instead of decimal values. Most references for
  150. INTERRUPTs use hexadecimal numbers rather than decimal numbers.
  151.  
  152. For some INTERRUPTs, it is necessary to set the high-order or
  153. low-order byte of a register. These bytes are usually referred to in
  154. the technical literature with H and L instead of X. For example, the
  155. high and low bytes of the BX register are BH and BL, respectively. To
  156. assign the registers when given high and low bytes, concatenate the
  157. hexadecimal values. For example, if you need to assign CH the value 2B
  158. hex and CL the value 3D hex, you would assign CX as follows:
  159.  
  160.    inregs.CX = &H2B3D     ' High byte = &H2B    Low byte = &H3D
  161.  
  162. If you are given only 1 byte (high or low), the other byte can be
  163. assigned 00 (two zeros). For example, you would set AH to the value 01
  164. hex as follows:
  165.  
  166.    inregs.AX = &H0100     ' High byte = &H01    Low byte ignored(00)
  167.  
  168. Note: The above statement is NOT equivalent to "inregs.AX=&H01". You
  169. must specify the low-order byte or the value will be stored as &H0001.
  170.  
  171. Once you have set the values of the input registers, you are ready to
  172. make the CALL. The CALL INTERRUPT syntax is as follows:
  173.  
  174.    CALL INTERRUPT(IntNum%, inregs, outregs)
  175.  
  176. If an INTERRUPT returns any values, those values will be passed back
  177. in the outregs variable. As with inregs, values will often be passed
  178. in the high or low bytes of a register. The routine, BreakWord(), in
  179. the example section below breaks a register into the 2-byte values.
  180.  
  181. With many INTERRUPTs, you need to check only a single bit (or a few
  182. bits) of any register. This is done using the bitwise operators AND,
  183. OR, XOR, and NOT. For example, the following statement will check to
  184. see if the third bit of AX is set:
  185.  
  186.    IF (outregs.AX AND &H4) THEN     ' 4 (hex) = 100 (binary)
  187.      PRINT "3rd Bit is on"
  188.    END IF
  189.  
  190. Example of CALL INTERRUPT
  191. -------------------------
  192.  
  193. The following program gives an example of the CALL INTERRUPT and
  194. provides two utility SUB programs for processing output:
  195.  
  196. '__________________________ INTSKEL.BAS _________________________
  197. '
  198. '     Skeleton program for calling DOS or BIOS interrupts from
  199. '     QuickBASIC.
  200. '
  201. '     NOTE: The QuickBASIC environment must be started with the
  202. '           /L option to load the default QB.QLB Quick library.
  203. '           This Quick library provides support for CALL INTERRUPT
  204. '           and CALL INTERRUPTX.
  205. '
  206. '     There are also two SUBPROGRAMS, BreakWord() and IntToBin(), that
  207. '     you may find useful when CALLing INTERRUPTs.
  208. '
  209. '_________________________________________________________________
  210.  
  211. DEFINT A-Z
  212. CONST TRUE = -1
  213. CONST FALSE = NOT TRUE
  214.  
  215. '$INCLUDE: 'QB.BI'                'Take a look at what is in this file
  216.  
  217. DIM inregs AS RegType, outregs AS RegType
  218.  
  219. '---------------------------------------------------------------------
  220. ' Load Registers with the required input parameters for the call that
  221. ' you want to make. (See any reference to DOS and/or BIOS calls.)
  222. '
  223. ' Example: for Interrupt 10 Hex, function 0A Hex (BIOS Write Char)
  224. '          AH = OA   Note: The function number usually goes in AH
  225. '          AL = Character Code (ASCII)
  226. '          BH = Video Page Number = 0 normally
  227. '          BL = Color in graphics mode
  228. '          CX = Number of these characters to write to screen
  229. '--------------------------------------------------------------------
  230. CLS
  231. character% = &HFB    'Character 251 decimal, square root symbol
  232. functnum% = &HA00    'Remember you want function in the HIGH Byte of AX
  233.  
  234.     'VERY IMPORTANT! Don't put the function number into
  235.     'the wrong byte of AX. Read [PROGRAM WILL HANG]
  236.  
  237. inregs.ax = character% OR &HA00
  238. inregs.cx = 2000      'Fill the screen
  239. CALL interrupt(&H10, inregs, outregs)
  240.  
  241.  
  242. DEFINT A-Z
  243. '_____________________________________________________________________
  244. '
  245. '     BreakWord() takes an integer argument and returns two integers
  246. '     representing the high and low bytes of the original.
  247. '_____________________________________________________________________
  248. '
  249. SUB BreakWord (dataword, highbyte, lowbyte)
  250.  
  251.    IF dataword < 0 THEN
  252.      highbyte = (dataword + 2 ^ 16) \ 256 'check for high BIT set
  253.    ELSE
  254.      highbyte = dataword \ 256            'integer divide off low byte
  255.    END IF
  256.  
  257.    lowbyte = dataword AND 255                'AND off the top byte
  258.  
  259. END SUB
  260.  
  261.  
  262.  
  263. DEFINT A-Z
  264. '_____________________________________________________________________
  265. '
  266. '    IntToBin() takes an INTEGER argument and produces a
  267. '    binary string representation of the INTEGER.
  268. '_____________________________________________________________________
  269. '
  270. SUB IntToBin (byte%, bin$)
  271. bin$ = ""
  272. temp% = byte%
  273.  
  274.      FOR i = 0 TO 7
  275.           IF temp% AND 1 THEN
  276.                bin$ = "1" + bin$
  277.           ELSE
  278.                bin$ = "0" + bin$
  279.           END IF
  280.            temp% = temp% \ 2
  281.      NEXT
  282.  
  283. END SUB
  284.  
  285. Differences between CALL INTERRUPT and CALL INTERRUPTX
  286. ------------------------------------------------------
  287.  
  288. The CALL INTERRUPT and CALL INTERRUPTX statements are very similar.
  289. Either statement allows you to make calls to DOS and BIOS INTERRUPTs.
  290.  
  291. The only difference is that, with INTERRUPTX, you can specify the DS
  292. and ES registers. (The documentation for INTERRUPTs -- see the
  293. following reference section -- will state whether those registers are
  294. necessary. For most INTERRUPTs, they are not needed.)
  295.  
  296. References for Documentation on INTERRUPTs
  297. ------------------------------------------
  298.  
  299. The following books are excellent resources for the different
  300. INTERRUPTs available from DOS and BIOS. Be aware that the code in
  301. these books is written in assembly language; however, they give the
  302. necessary input and output by register.
  303.  
  304. 1. "Advanced MS-DOS Programming, Second Edition" by Ray Duncan,
  305.    published by Microsoft Press (1988)
  306.  
  307. 2. "The New Peter Norton Programmer's Guide to the IBM PC & PS/2" by
  308.    Peter Norton, published by Microsoft Press (1988)
  309.  
  310. Additional reference words: QB4INT.ARC S12340.EXE
  311.